/**
 * 页面监听器基类
 * 用于管理事件监听器和大列表数据优化
 */

const timerHelper = require('./timer_helper.js');

/**
 * 页面监听器辅助类
 * 提供事件监听管理和数据优化功能
 */
class PageListener {
  /**
   * 构造函数
   * @param {Page} pageInstance 页面实例
   */
  constructor(pageInstance) {
    this.page = pageInstance;
    this.listeners = new Map();
    this.virtualListData = null;
    
    // 自动注入生命周期钩子
    this._injectLifecycleHooks();
  }
  
  /**
   * 添加事件监听器
   * @param {string} eventName 事件名称
   * @param {Function} callback 回调函数
   */
  addListener(eventName, callback) {
    if (!this.listeners.has(eventName)) {
      this.listeners.set(eventName, []);
    }
    
    const callbacks = this.listeners.get(eventName);
    callbacks.push(callback);
    
    // 注册系统事件
    if (eventName === 'networkStatusChange') {
      wx.onNetworkStatusChange(callback);
    } else if (eventName === 'userInfoChange') {
      wx.onUserInfoChange(callback);
    } else if (eventName === 'accelerometerChange') {
      wx.onAccelerometerChange(callback);
    } else if (eventName === 'compassChange') {
      wx.onCompassChange(callback);
    } else if (eventName === 'deviceMotionChange') {
      wx.onDeviceMotionChange(callback);
    }
  }
  
  /**
   * 移除事件监听器
   * @param {string} eventName 事件名称
   * @param {Function} callback 回调函数，如果不提供则移除所有该事件的监听器
   */
  removeListener(eventName, callback) {
    if (!this.listeners.has(eventName)) return;
    
    if (callback) {
      // 移除特定回调
      const callbacks = this.listeners.get(eventName);
      const index = callbacks.indexOf(callback);
      if (index !== -1) {
        callbacks.splice(index, 1);
      }
      
      // 如果系统事件，取消监听
      if (eventName === 'networkStatusChange') {
        wx.offNetworkStatusChange(callback);
      } else if (eventName === 'userInfoChange') {
        wx.offUserInfoChange(callback);
      } else if (eventName === 'accelerometerChange') {
        wx.offAccelerometerChange(callback);
      } else if (eventName === 'compassChange') {
        wx.offCompassChange(callback);
      } else if (eventName === 'deviceMotionChange') {
        wx.offDeviceMotionChange(callback);
      }
    } else {
      // 移除所有该事件监听器
      const callbacks = this.listeners.get(eventName);
      
      // 如果是系统事件，取消所有监听
      if (eventName === 'networkStatusChange') {
        callbacks.forEach(cb => wx.offNetworkStatusChange(cb));
      } else if (eventName === 'userInfoChange') {
        callbacks.forEach(cb => wx.offUserInfoChange(cb));
      } else if (eventName === 'accelerometerChange') {
        callbacks.forEach(cb => wx.offAccelerometerChange(cb));
      } else if (eventName === 'compassChange') {
        callbacks.forEach(cb => wx.offCompassChange(cb));
      } else if (eventName === 'deviceMotionChange') {
        callbacks.forEach(cb => wx.offDeviceMotionChange(cb));
      }
      
      this.listeners.delete(eventName);
    }
  }
  
  /**
   * 触发事件
   * @param {string} eventName 事件名称
   * @param {*} data 事件数据
   */
  triggerEvent(eventName, data) {
    if (!this.listeners.has(eventName)) return;
    
    const callbacks = this.listeners.get(eventName);
    callbacks.forEach(callback => {
      try {
        callback(data);
      } catch (e) {
        console.error(`事件处理器错误: ${eventName}`, e);
      }
    });
  }
  
  /**
   * 清理所有事件监听器
   */
  clearAllListeners() {
    // 系统事件需要特殊处理
    if (this.listeners.has('networkStatusChange')) {
      const callbacks = this.listeners.get('networkStatusChange');
      callbacks.forEach(cb => wx.offNetworkStatusChange(cb));
    }
    
    if (this.listeners.has('userInfoChange')) {
      const callbacks = this.listeners.get('userInfoChange');
      callbacks.forEach(cb => wx.offUserInfoChange(cb));
    }
    
    if (this.listeners.has('accelerometerChange')) {
      const callbacks = this.listeners.get('accelerometerChange');
      callbacks.forEach(cb => wx.offAccelerometerChange(cb));
    }
    
    if (this.listeners.has('compassChange')) {
      const callbacks = this.listeners.get('compassChange');
      callbacks.forEach(cb => wx.offCompassChange(cb));
    }
    
    if (this.listeners.has('deviceMotionChange')) {
      const callbacks = this.listeners.get('deviceMotionChange');
      callbacks.forEach(cb => wx.offDeviceMotionChange(cb));
    }
    
    this.listeners.clear();
  }
  
  /**
   * 设置虚拟列表数据
   * @param {Array} fullData 完整数据列表
   * @param {Object} options 配置选项
   * @param {number} options.pageSize 每页数量
   * @param {string} options.listKey 数据列表在page.data中的键
   * @param {Function} options.renderItem 渲染项目回调
   */
  setVirtualList(fullData, options = {}) {
    const { 
      pageSize = 20, 
      listKey = 'list',
      renderItem = null 
    } = options;
    
    this.virtualListData = {
      fullData: fullData || [],
      pageSize,
      listKey,
      renderItem,
      currentPage: 1,
      isLoading: false
    };
    
    // 初始化显示第一页
    this._renderVirtualListPage(1);
    
    // 设置页面的加载更多方法
    this.page.loadMoreItems = () => {
      this.loadMoreVirtualItems();
    };
  }
  
  /**
   * 加载更多虚拟列表项目
   */
  loadMoreVirtualItems() {
    if (!this.virtualListData || this.virtualListData.isLoading) return;
    
    const vl = this.virtualListData;
    const totalPages = Math.ceil(vl.fullData.length / vl.pageSize);
    
    if (vl.currentPage >= totalPages) return;
    
    vl.isLoading = true;
    vl.currentPage++;
    
    // 使用定时器模拟异步加载，避免阻塞UI
    timerHelper.setTimeout(this.page, 'timeout_loadmore', () => {
      this._renderVirtualListPage(vl.currentPage);
      vl.isLoading = false;
    }, 100);
  }
  
  /**
   * 渲染虚拟列表指定页
   * @private
   * @param {number} page 页码
   */
  _renderVirtualListPage(page) {
    const vl = this.virtualListData;
    if (!vl) return;
    
    const start = 0;
    const end = page * vl.pageSize;
    const visibleData = vl.fullData.slice(start, end);
    
    // 如果有自定义渲染函数，调用它
    const renderedData = vl.renderItem 
      ? visibleData.map(vl.renderItem) 
      : visibleData;
    
    // 更新页面数据
    const updateData = {};
    updateData[vl.listKey] = renderedData;
    this.page.setData(updateData);
  }
  
  /**
   * 注入生命周期钩子
   * @private
   */
  _injectLifecycleHooks() {
    // 保存原始生命周期方法
    const originalOnUnload = this.page.onUnload;
    const originalOnHide = this.page.onHide;
    const originalOnShow = this.page.onShow;
    const originalOnReachBottom = this.page.onReachBottom;
    
    // 重写onUnload
    this.page.onUnload = function() {
      // 执行原始onUnload
      if (originalOnUnload) {
        originalOnUnload.call(this);
      }
      
      // 清理所有监听器
      if (this._pageListener) {
        this._pageListener.clearAllListeners();
      }
    };
    
    // 重写onHide
    this.page.onHide = function() {
      // 执行原始onHide
      if (originalOnHide) {
        originalOnHide.call(this);
      }
    };
    
    // 重写onShow
    this.page.onShow = function() {
      // 执行原始onShow
      if (originalOnShow) {
        originalOnShow.call(this);
      }
    };
    
    // 重写onReachBottom，支持虚拟列表加载更多
    this.page.onReachBottom = function() {
      // 执行原始onReachBottom
      if (originalOnReachBottom) {
        originalOnReachBottom.call(this);
      }
      
      // 如果有虚拟列表，加载更多
      if (this._pageListener && this._pageListener.virtualListData) {
        this._pageListener.loadMoreVirtualItems();
      }
    };
    
    // 将本实例存储到页面实例中
    this.page._pageListener = this;
  }
}

/**
 * 为页面创建监听器实例
 * @param {Page} pageInstance 页面实例
 * @returns {PageListener} 页面监听器实例
 */
function createPageListener(pageInstance) {
  return new PageListener(pageInstance);
}

module.exports = {
  createPageListener
}; 